//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2007
//
// Set house numbers info.
//

# include "StdAfx.h"
//# include "Resource.h"
# include "SetNumbers.h"
# include "UndoRedo.h"
//# include "Map.h"
# include "Label.h"
# include "NodesExtra.h"

static
const numbers_t & _GetNumbers (const rgn_t & _rgn, size_t _cElement, size_t _cPoint) {
	const rgn_element_t & element = _rgn.elements [_cElement];
	if (element.pExtra && _cPoint < element.pExtra->PointExtras.size ())
		return element.pExtra->PointExtras [_cPoint].Numbers;
	else {
		static numbers_t s_numbersDef;
		return s_numbersDef;
	}
}

class CSetNumbersAction : public CEditAction {
  public:
	CSetNumbersAction (rgn_t * _pRgn, size_t _cElement, size_t _cPoint, const numbers_t & _Numbers) :
		m_pRgn (_pRgn),
		m_cElement (_cElement),
		m_cPoint (_cPoint),
		m_NumbersOld (_GetNumbers (* _pRgn, _cElement, _cPoint)),
		m_NumbersNew (_Numbers),
		m_bWasModified ((_pRgn->dwFlags & rgn_t::fModified) != 0)
	{}

	virtual void GetName (string_t & _str) const;
	virtual cu_t CanUndo () const {return cuYes;}
	virtual bool Do ();
	virtual void Undo ();
	virtual void Redo ();

  private:
	rgn_t *    const m_pRgn;
	size_t     const m_cElement;
	size_t     const m_cPoint;
	const numbers_t m_NumbersOld;
	const numbers_t m_NumbersNew;
	bool       const m_bWasModified;
};

void CSetNumbersAction::GetName (string_t & _str) const {
	_str.append ("set numbers [");
	GetHintText (* m_pRgn, _str);
	_str.append ("]");
}

bool CSetNumbersAction::Do () {
	CCritSec::CLock lock (g_cs);

	assert (m_pRgn);
	assert (m_cElement < m_pRgn->elements.size ());
	rgn_element_t & element = m_pRgn->elements [m_cElement];

	assert (m_cPoint < element.points.size ());
	element.pExtra->PointExtras.resize (__max (m_cPoint + 1, element.points.size ()));
	element.pExtra->PointExtras [m_cPoint].Numbers = m_NumbersNew;

//	m_pRgn->RefreshAttributes (g_map);
	m_pRgn->dwFlags |= rgn_t::fModified;

	return true;
}

void CSetNumbersAction::Undo () {
	CCritSec::CLock lock (g_cs);

	assert (m_pRgn);
	assert (m_cElement < m_pRgn->elements.size ());
	rgn_element_t & element = m_pRgn->elements [m_cElement];

	assert (m_cPoint < element.points.size ());
	element.pExtra->PointExtras [m_cPoint].Numbers = m_NumbersOld;

//	m_pRgn->RefreshAttributes (g_map);
	if (! m_bWasModified)
		m_pRgn->dwFlags &= ~rgn_t::fModified;
}

void CSetNumbersAction::Redo () {
	CSetNumbersAction::Do ();
}

//////////////////////////////////////

void SetNumbers (rgn_t * _pRgn, size_t _cElement, size_t _cPoint, const numbers_t & _Numbers) {
	assert (_pRgn);
	assert (_cElement < _pRgn->elements.size ());
	assert (_cPoint < _pRgn->elements [_cElement].points.size ());

	PerformEditAction (new CSetNumbersAction (_pRgn, _cElement, _cPoint, _Numbers));
}
